package com.kxmall.dashboard.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kxmall.categorize.domain.HsWasteCategorize;
import com.kxmall.categorize.mapper.HsWasteCategorizeMapper;
import com.kxmall.count.countVO.LargeScreenCommonVO;
import com.kxmall.count.countVO.LargeScreenVO;
import com.kxmall.count.countVO.RecoveryChartVO;
import com.kxmall.count.countVO.WasteCountItemVO;
import com.kxmall.huishou.domain.*;
import com.kxmall.huishou.mapper.*;
import com.kxmall.huishou.service.IHsSettlementOrderService;
import com.kxmall.huishou.service.IHsUserWasteService;
import com.kxmall.rider.domain.KxRider;
import com.kxmall.rider.mapper.KxRiderMapper;
import com.kxmall.user.domain.KxUser;
import com.kxmall.user.mapper.KxUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class StatisticsBizService {

    private final HsAppointmentOrderMapper hsAppointmentOrderMapper;   //回收预约订单

    private final HsSettlementOrderMapper hsSettlementOrderMapper;   //回收结算订单
    private final IHsSettlementOrderService hsSettlementOrderService;   //回收结算订单

    private final HsUserWasteMapper hsUserWasteMapper;   //回收废品信息
    private final IHsUserWasteService hsUserWasteService;   //回收废品信息

    private final HsWasteCategorizeMapper hsWasteCategorizeMapper;   //废品分类信息

    private final HsWasteSiteMapper hsWasteSiteMapper;   //废品回收站信息

    private final KxRiderMapper kxRiderMapper;   //回收员申请信息

    private final HsWasteCountMapper hsWasteCountMapper;   //废品回收统计信息

    private final HsWasteHandleTypeMapper hsWasteHandleTypeMapper;   //垃圾处理方式信息

    private final HsRecoveryVehicleMapper hsRecoveryVehicleMapper;   //车辆信息

    private final KxUserMapper kxUserMapper;   //用户信息

    public LargeScreenVO getScreenData(){
        LargeScreenVO largeScreenVO = new LargeScreenVO();
        //废品回收统计
        List<HsWasteCount> hsWasteCounts = hsWasteCountMapper.selectList();
        HsWasteCount hsWasteCount = new HsWasteCount();
        if (CollUtil.isNotEmpty(hsWasteCounts)){
            hsWasteCount = hsWasteCounts.get(0);
        }
        // 用户总数
        Long kxUsers = kxUserMapper
                .selectCount(Wrappers.<KxUser>lambdaQuery().eq(KxUser::getIsDel, 0));
        hsWasteCount.setUserCount(String.valueOf(kxUsers));
        // 回收员数
        Long kxRiderNum = kxRiderMapper
                .selectCount(Wrappers.<KxRider>lambdaQuery().eq(KxRider::getState, 1));
        hsWasteCount.setRecoveryPersonNum(String.valueOf(kxRiderNum));
        // 废品种类数
        Long size = hsWasteCategorizeMapper
                .selectCount(Wrappers.<HsWasteCategorize>lambdaQuery()
                        .ne(HsWasteCategorize::getParentId, 0));
        hsWasteCount.setRecoveryTypeNum(String.valueOf(size));

        // 将 HsWasteCount 转换为 WasteCountItemVO 列表
        List<WasteCountItemVO> wasteCountList = convertToWasteCountList(hsWasteCount);
        largeScreenVO.setWasteCount(wasteCountList);
        //垃圾处理方式对象
        largeScreenVO.setHandleTypeList(hsWasteHandleTypeMapper.selectList());
        //车辆信息 在线 离线
        List<HsRecoveryVehicle> vehicleList = hsRecoveryVehicleMapper.selectList();
        largeScreenVO.setRecoveryVehicleList(vehicleList);
        largeScreenVO.setVehicleOn(vehicleList.stream()
                .filter(vehicle -> vehicle.getStatus() == 1)
                .count());
        largeScreenVO.setVehicleOff(vehicleList.stream()
                .filter(vehicle -> vehicle.getStatus() == 0)
                .count());

        // 预约订单信息
        List<LargeScreenCommonVO> orderList = new ArrayList<>();
        LambdaQueryWrapper<HsAppointmentOrder> qAO = new LambdaQueryWrapper<>();
//        qAO.eq(HsAppointmentOrder::getStatus,4);
        qAO.orderByDesc(HsAppointmentOrder::getCreateTime);
        Page<HsAppointmentOrder> hsAppointmentOrderPage = hsAppointmentOrderMapper.selectPage(new Page<>(1,10),qAO);
        for (HsAppointmentOrder hsAppointmentOrder : hsAppointmentOrderPage.getRecords()) {
            LargeScreenCommonVO orderCommonVO = new LargeScreenCommonVO();
//            HsAppointmentOrderVo appointmentOrderVo = hsAppointmentOrderMapper.selectVoById(hsSettlementOrder.getAppointOrderId());
            orderCommonVO.setAddress(hsAppointmentOrder.getAddress());
            orderCommonVO.setTime(hsAppointmentOrder.getCreateTime());
            orderCommonVO.setPhone(hsAppointmentOrder.getPhone());
            orderList.add(orderCommonVO);

        }
        // 废品信息
        List<LargeScreenCommonVO> wasteList = new ArrayList<>();
        LambdaQueryWrapper<HsUserWaste> qUW = new LambdaQueryWrapper<>();
        qUW.eq(HsUserWaste::getOrderType,1);
        qUW.orderByDesc(HsUserWaste::getCreateTime);
        Page<HsUserWaste> hsUserWastePage = hsUserWasteMapper.selectPage(new Page<>(1, 5), qUW);
        List<HsUserWaste> hsUserWastes = hsUserWastePage.getRecords();
        for (HsUserWaste hsUserWaste : hsUserWastes) {
            LargeScreenCommonVO wasteCommonVO = new LargeScreenCommonVO();
            wasteCommonVO.setTime(hsUserWaste.getCreateTime());
            wasteCommonVO.setType(hsUserWaste.getCategorizeName());
            wasteCommonVO.setWeight(hsUserWaste.getWeight());
            wasteList.add(wasteCommonVO);
        }
        largeScreenVO.setSettlementOrderList(orderList);
        largeScreenVO.setWasteList(wasteList);

        // 废品各分类总量统计
        LambdaQueryWrapper<HsSettlementOrder> qSO2 = new LambdaQueryWrapper<>();
        qSO2.eq(HsSettlementOrder::getStatus,4);
        List<HsSettlementOrder> settlementOrderList2 = hsSettlementOrderMapper.selectList(qSO2);
        List<Long> ids = settlementOrderList2.stream()
                .map(HsSettlementOrder::getId)
                .collect(Collectors.toList());
        List<RecoveryChartVO> recoveryChartVOS = new ArrayList<>();
        if (CollUtil.isNotEmpty(ids)){
            LambdaQueryWrapper<HsUserWaste> qUW2 = new LambdaQueryWrapper<>();
            qUW2.in(HsUserWaste::getOrderId,ids);
            qUW2.eq(HsUserWaste::getOrderType,1);
            recoveryChartVOS = hsUserWasteService.queryChartType(qUW2);
            // 值已经在 queryChartType 方法中格式化了（包含单位）
        }

        largeScreenVO.setChartTypeList(recoveryChartVOS);

        // 周 回收总重量
        largeScreenVO.setChartWeekList(hsSettlementOrderService.getChartVOListSeven());

        return largeScreenVO;
    }

    public LargeScreenVO getAppCardData(){
        LargeScreenVO largeScreenVO = new LargeScreenVO();
        //废品回收统计
        List<HsWasteCount> hsWasteCounts = hsWasteCountMapper.selectList();
        HsWasteCount hsWasteCount = new HsWasteCount();
        if (CollUtil.isNotEmpty(hsWasteCounts)){
            hsWasteCount = hsWasteCounts.get(0);
        }
        // 用户总数
        Long kxUsers = kxUserMapper
                .selectCount(Wrappers.<KxUser>lambdaQuery().eq(KxUser::getIsDel, 0));
        hsWasteCount.setUserCount(String.valueOf(kxUsers));
        // 回收员数
        Long kxRiderNum = kxRiderMapper
                .selectCount(Wrappers.<KxRider>lambdaQuery().eq(KxRider::getState, 1));
        hsWasteCount.setRecoveryPersonNum(String.valueOf(kxRiderNum));
        // 废品种类数
        Long size = hsWasteCategorizeMapper
                .selectCount(Wrappers.<HsWasteCategorize>lambdaQuery()
                        .ne(HsWasteCategorize::getParentId, 0));
        hsWasteCount.setRecoveryTypeNum(String.valueOf(size));

        // 将 HsWasteCount 转换为 WasteCountItemVO 列表（临时设置，后面会重新计算）
        List<WasteCountItemVO> wasteCountList = convertToWasteCountList(hsWasteCount);
        largeScreenVO.setWasteCount(wasteCountList);

        // 废品各分类总量统计
        LambdaQueryWrapper<HsSettlementOrder> qSO2 = new LambdaQueryWrapper<>();
        qSO2.eq(HsSettlementOrder::getStatus,4);
        List<HsSettlementOrder> settlementOrderList2 = hsSettlementOrderMapper.selectList(qSO2);
        List<Long> ids = settlementOrderList2.stream()
                .map(HsSettlementOrder::getId)
                .collect(Collectors.toList());
        List<RecoveryChartVO> recoveryChartVOS = new ArrayList<>();
        if (CollUtil.isNotEmpty(ids)){
            LambdaQueryWrapper<HsUserWaste> qUW2 = new LambdaQueryWrapper<>();
            qUW2.in(HsUserWaste::getOrderId,ids);
            qUW2.eq(HsUserWaste::getOrderType,1);
            recoveryChartVOS = hsUserWasteService.queryChartType(qUW2);
            // 值已经在 queryChartType 方法中格式化了（包含单位）
        }

        // chartTypeList 的值已经在 queryChartType 方法中格式化了，这里不需要再处理

        largeScreenVO.setChartTypeList(recoveryChartVOS);

        // 按单位分类统计并设置到不同的总量字段
        if (CollUtil.isNotEmpty(recoveryChartVOS)) {
            BigDecimal weightTotal = BigDecimal.ZERO;  // 重量总计（吨）
            BigDecimal countTotal2 = BigDecimal.ZERO;  // 台数总计
            BigDecimal countTotal3 = BigDecimal.ZERO;  // 辆数总计

            for (RecoveryChartVO chartVO : recoveryChartVOS) {
                if (StrUtil.isNotBlank(chartVO.getValue()) && StrUtil.isNotBlank(chartVO.getUnit())) {
                    String unit = chartVO.getUnit().toLowerCase().trim();
                    BigDecimal numericValue = extractNumericValue(chartVO.getValue());

                    switch (unit) {
                        case "台":
                            countTotal2 = countTotal2.add(numericValue);
                            break;
                        case "辆":
                            countTotal3 = countTotal3.add(numericValue);
                            break;
                        case "吨":
                        case "t":
                            // 如果是吨，直接累加
                            weightTotal = weightTotal.add(numericValue);
                            break;
                        case "千吨":
                            // 如果是千吨，需要转换为吨再累加
                            weightTotal = weightTotal.add(numericValue.multiply(new BigDecimal("1000")));
                            break;
                        case "kg":
                        case "千克":
                        case "g":
                        case "克":
                        default:
                            // 其他重量单位，已经在queryChartType中转换为吨了
                            weightTotal = weightTotal.add(numericValue);
                            break;
                    }
                }
            }

            // 设置不同类型的总量（重量保留2位小数）
            hsWasteCount.setWasteTotal(weightTotal.setScale(2, RoundingMode.HALF_UP));      // 重量总计（吨）
            hsWasteCount.setWasteTotal2(countTotal2);     // 台数总计
            hsWasteCount.setWasteTotal3(countTotal3);     // 辆数总计

            // 重新转换为 WasteCountItemVO 列表（包含更新后的统计数据）
            List<WasteCountItemVO> updatedWasteCountList = convertToWasteCountList(hsWasteCount);
            largeScreenVO.setWasteCount(updatedWasteCountList);
        }


        //wasteCount  改成  给每个字段都添加添加txt  value
//        "wasteCount": [{
//            txt: '绿色回收网点',
//                    val: '0'
//        },
//        {
//            txt: '绿色分拣中心',
//                    val: '0'
//        },
//        {
//            txt: '回收总量',
//                    val: '0'
//        },
//        {
//            txt: '碳排放量',
//                    val: '0'
//        },
//        {
//            txt: '中转场',
//                    val: '0'
//        },
//        {
//            txt: '回收种类',
//                    val: '0'
//        },
//        {
//            txt: '回收员数量',
//                    val: '0'
//        },
//        {
//            txt: '用户数量',
//                    val: '0'
//        }
//					],
        return largeScreenVO;
    }

    /**
     * 将 HsWasteCount 对象转换为 WasteCountItemVO 列表
     * @param hsWasteCount 废品统计对象
     * @return WasteCountItemVO 列表
     */
    private List<WasteCountItemVO> convertToWasteCountList(HsWasteCount hsWasteCount) {
        List<WasteCountItemVO> wasteCountList = new ArrayList<>();

        // 绿色回收网点
        wasteCountList.add(new WasteCountItemVO("绿色回收网点",
            hsWasteCount.getGreenWeb() != null ? hsWasteCount.getGreenWeb().toString() : "0"));

        // 绿色分拣中心
        wasteCountList.add(new WasteCountItemVO("绿色分拣中心",
            hsWasteCount.getGreenCore() != null ? hsWasteCount.getGreenCore().toString() : "0"));

        // 回收总量（自动转换吨/千吨）
        wasteCountList.add(new WasteCountItemVO("回收总量",
            formatWeightDisplay(hsWasteCount.getWasteTotal())));

        // 碳排放量
        wasteCountList.add(new WasteCountItemVO("碳排放量",
            hsWasteCount.getCarbonEmissionTotal() != null ? hsWasteCount.getCarbonEmissionTotal().toString() : "0"));

        // 中转场
        wasteCountList.add(new WasteCountItemVO("中转场",
            hsWasteCount.getTransferPlant() != null ? hsWasteCount.getTransferPlant().toString() : "0"));

        // 回收种类
        wasteCountList.add(new WasteCountItemVO("回收种类",
            hsWasteCount.getRecoveryTypeNum() != null ? hsWasteCount.getRecoveryTypeNum() : "0"));

        // 回收员数量
        wasteCountList.add(new WasteCountItemVO("回收员数量",
            hsWasteCount.getRecoveryPersonNum() != null ? hsWasteCount.getRecoveryPersonNum() : "0"));

        // 用户数量
        wasteCountList.add(new WasteCountItemVO("用户数量",
            hsWasteCount.getUserCount() != null ? hsWasteCount.getUserCount() : "0"));

        // 如果有台数统计，添加台数统计
        if (hsWasteCount.getWasteTotal2() != null && hsWasteCount.getWasteTotal2().compareTo(BigDecimal.ZERO) > 0) {
            wasteCountList.add(new WasteCountItemVO("回收总量(台)",
                hsWasteCount.getWasteTotal2().setScale(0, RoundingMode.HALF_UP).toString() + "台"));
        }

        // 如果有辆数统计，添加辆数统计
        if (hsWasteCount.getWasteTotal3() != null && hsWasteCount.getWasteTotal3().compareTo(BigDecimal.ZERO) > 0) {
            wasteCountList.add(new WasteCountItemVO("回收总量(辆)",
                hsWasteCount.getWasteTotal3().setScale(0, RoundingMode.HALF_UP).toString() + "辆"));
        }

        return wasteCountList;
    }

    /**
     * 格式化重量显示（吨 -> 千吨）
     * 当重量 >= 1000吨时，转换为千吨显示
     * @param weightInTons 重量（吨）
     * @return 格式化后的重量字符串
     */
    private String formatWeightDisplay(BigDecimal weightInTons) {
        if (weightInTons == null) {
            return "0.00吨";
        }

        // 保留2位小数
        BigDecimal formattedWeight = weightInTons.setScale(2, RoundingMode.HALF_UP);

        // 如果大于等于1000吨，转换为千吨
        if (formattedWeight.compareTo(new BigDecimal("1000")) >= 0) {
            BigDecimal weightInKiloTons = formattedWeight.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP);
            return weightInKiloTons.toString() + "千吨";
        } else {
            return formattedWeight.toString() + "吨";
        }
    }

    /**
     * 格式化图表中的重量数值（仅返回数值部分）
     * 当重量 >= 1000吨时，转换为千吨的数值
     * @param weightInTons 重量（吨）
     * @return 格式化后的重量数值字符串
     */
    private String formatWeightForChart(BigDecimal weightInTons) {
        if (weightInTons == null) {
            return "0.00";
        }

        // 保留2位小数
        BigDecimal formattedWeight = weightInTons.setScale(2, RoundingMode.HALF_UP);

        // 如果大于等于1000吨，转换为千吨
        if (formattedWeight.compareTo(new BigDecimal("1000")) >= 0) {
            BigDecimal weightInKiloTons = formattedWeight.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP);
            return weightInKiloTons.toString();
        } else {
            return formattedWeight.toString();
        }
    }

    /**
     * 从包含单位的字符串中提取数值
     * @param valueWithUnit 包含单位的值字符串，如 "123.45吨"、"10台"
     * @return 提取出的数值
     */
    private BigDecimal extractNumericValue(String valueWithUnit) {
        if (StrUtil.isBlank(valueWithUnit)) {
            return BigDecimal.ZERO;
        }

        // 使用正则表达式提取数字部分（包括小数点）
        String numericPart = valueWithUnit.replaceAll("[^0-9.]", "");

        try {
            return new BigDecimal(numericPart);
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }

}
